import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:xindong/common/xindong_define.dart';
import 'package:xindong/common/xindong_methods.dart';
import 'package:xindong/common/xindong_types.dart';
import 'package:xindong/manager/xindong_user_controller.dart';
import 'package:xindong/models/chat_message/xindong_custom_gift_message.dart';
import 'package:xindong/models/chat_message/xindong_custom_message.dart';
import 'package:xindong/routes/call/controller/xindong_call_controller.dart';
import 'package:xindong/utils/queue/xindong_timer_queue.dart';
import 'package:xindong/widgets/floating_screen/xindong_piao_ping_animation_container.dart';
import 'package:xindong/widgets/floating_screen/xindong_piao_ping_gift_cell.dart';

// 飘屏动画容器
// child 组件（要自带尺寸）
class XinDongPiaoPingSingleton extends GetxController {
  final double itemHeight = 44.0;
  final int milliseconds = 5000;
  double slideHeight = 88.9;

  // 悬浮层
  OverlayEntry? overlayEntry;

  // 自定义
  late XinDongTimerQueue timerQueue; // 队列
  late Widget showWidget = const SizedBox(); // 给外部显示的视图

  void heightSetState(double dy) {
    if (slideHeight + dy > statusBarHeight && slideHeight + dy < screenHeight - kTabBarHeight - itemHeight) {
      slideHeight += dy;
      update();
    }
  }

  // 飘屏需要下移
  double get needMoveDownOffset {
    if (XinDongCallController.to.status == XinDongCallStatus.connecting) {
      return statusBarHeight + 96.0 + 26;
    }
    return statusBarHeight + kAppBarHeight + 10;
  }

  /// 添加到队列
  ///
  /// isLimitGirl 是否限制女的才显示
  void addQueue(XinDongCustomMessage? object, {bool isLimitGirl = false}) async {
    if (object == null) {
      return;
    }
    // 限制主播？不是主播不飘屏
    if (isLimitGirl && XinDongUserController.to.sex == Gender.female) {
      return;
    }
    // 礼物
    if (object.type != ChatType.gift) {
      return;
    }
    timerQueue.addQueue(object, milliseconds: milliseconds);
    show();
  }

  // 清除
  void clear() {
    timerQueue.clear();
    hide();
  }

  // 初始化动画队列
  void init() {
    slideHeight = needMoveDownOffset;
    timerQueue = XinDongTimerQueue(
      maxCount: 1,
      startCallback: (object) {
        // this.showWidget = Container(color: DZColors.mainColor,);
        showWidget = XinDongPiaoPingAnimationContainer(
          milliseconds: milliseconds,
          child: buildContainer(object), // 要自带高度
        );
        update();
      },
      endCallback: () {
        showWidget = const SizedBox();
        hide();
      },
    );
  }

  // 要具体宽高
  Widget buildContainer(XinDongCustomMessage object) {
    Widget child = const SizedBox();
    switch (object.type) {
      case ChatType.gift:
        final message = object as XinDongCustomGiftMessage;
        child = XinDongPiaoPingGiftCell(itemHeight: itemHeight, message: message);
        break;
      default:
        mDebugPrint("不支持的类型");
        break;
    }
    return child;
  }

  Future<dynamic> show() async {
    BuildContext? context = navigatorKey.currentContext;
    if (context == null) {
      return;
    }
    final overlay = Overlay.of(context);
    // 避免重复添加
    if (overlayEntry == null) {
      overlayEntry = OverlayEntry(
        opaque: false,
        maintainState: false,
        builder: (BuildContext context) {
          return GetBuilder<XinDongPiaoPingSingleton>(builder: (controller) {
            return Container(
              margin: EdgeInsets.only(top: slideHeight),
              width: screenWidth,
              height: itemHeight,
              child: GestureDetector(
                onPanUpdate: (DragUpdateDetails e) {
                  heightSetState(e.delta.dy);
                },
                onPanEnd: (DragEndDetails e) {},
                child: showWidget,
              ),
            );
          });
        },
      );
      WidgetsBinding.instance.addPostFrameCallback((_) => overlay.insert(overlayEntry!));
    }
  }

  void hide() {
    overlayEntry?.remove();
    overlayEntry = null;
  }

  /// ======== 单例
  // 工厂方法构造函数
  factory XinDongPiaoPingSingleton() => _getInstance();

  // instance的getter方法，singletonManager.instance获取对象
  static XinDongPiaoPingSingleton get instance => _getInstance();

  // 静态变量_instance，存储唯一对象
  static XinDongPiaoPingSingleton? _instance;

  // 获取对象
  static XinDongPiaoPingSingleton _getInstance() {
    _instance ??= XinDongPiaoPingSingleton._internal();
    return _instance!;
  }

  // 私有的自定义命名式构造方法，通过它实现一个类;
  // 子类不能继承internal
  // 不是关键字，可定义其他名字
  XinDongPiaoPingSingleton._internal() {
    //初始化(设置一些默认的)...
    init();
  }
}
